namespace TXLooker.WorkItemExtention.WIQL
{
    using System;
    using System.Collections;
    using System.Globalization;
    using System.Reflection;

    public abstract class Node : IEnumerable
    {
        private int m_endOffset = -1;
        private NodeType m_nodeType;
        private int m_startOffset = -1;

        protected Node(NodeType type)
        {
            this.m_nodeType = type;
        }

        public virtual void Bind(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            if (e != null)
            {
                e.VerifyNode(this, tableContext, fieldContext);
            }
        }

        protected void BindChildren(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            int count = this.Count;
            for (int i = 0; i < count; i++)
            {
                this[i].Bind(e, tableContext, fieldContext);
            }
        }

        public virtual bool CanCastTo(DataType type, CultureInfo culture)
        {
            return (this.DataType == type);
        }

        public Node FindNodeByOffset(int offset)
        {
            if ((offset >= 0) && ((this.m_startOffset == -1) || ((offset >= this.m_startOffset) && (offset < this.m_endOffset))))
            {
                int count = this.Count;
                for (int i = 0; i < count; i++)
                {
                    if (this[i] != null)
                    {
                        Node node2 = this[i].FindNodeByOffset(offset);
                        if (node2 != null)
                        {
                            return node2;
                        }
                    }
                }
                if (this.m_startOffset != -1)
                {
                    return this;
                }
            }
            return null;
        }

        protected bool GetChildrenCanCastTo(DataType type, CultureInfo culture)
        {
            int count = this.Count;
            for (int i = 0; i < count; i++)
            {
                if (!this[i].CanCastTo(type, culture))
                {
                    return false;
                }
            }
            return true;
        }

        protected DataType GetChildrenDataType()
        {
            int count = this.Count;
            if (count == 0)
            {
                return DataType.Void;
            }
            DataType dataType = this[0].DataType;
            for (int i = 1; i < count; i++)
            {
                if (this[i].DataType != dataType)
                {
                    return DataType.Unknown;
                }
            }
            return dataType;
        }

        protected bool GetChildrenIsConst()
        {
            int count = this.Count;
            for (int i = 0; i < count; i++)
            {
                if (!this[i].IsConst)
                {
                    return false;
                }
            }
            return true;
        }

        public IEnumerator GetEnumerator()
        {
            return new NodeEnumerator(this);
        }

        protected string JoinChildren(string sep)
        {
            string text = "";
            int count = this.Count;
            for (int i = 0; i < count; i++)
            {
                Node node = this[i];
                if (text.Length != 0)
                {
                    text = text + sep;
                }
                string text2 = node.ToString();
                if (node.Priority >= this.Priority)
                {
                    text = text + "(" + text2 + ")";
                }
                else
                {
                    text = text + text2;
                }
            }
            return text;
        }

        public virtual Node Optimize(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            if (e == null)
            {
                return this;
            }
            return e.OptimizeNode(this, tableContext, fieldContext);
        }

        protected void OptimizeChildren(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            int count = this.Count;
            for (int i = 0; i < count; i++)
            {
                this[i] = this[i].Optimize(e, tableContext, fieldContext);
            }
        }

        public virtual string ConstStringValue
        {
            get
            {
                return null;
            }
        }

        public abstract int Count { get; }

        public abstract DataType DataType { get; }

        public int EndOffset
        {
            get
            {
                return this.m_endOffset;
            }
            set
            {
                this.m_endOffset = value;
            }
        }

        public abstract bool IsConst { get; }

        public abstract bool IsScalar { get; }

        public abstract Node this[int i] { get; set; }

        public NodeType NodeType
        {
            get
            {
                return this.m_nodeType;
            }
        }

        public abstract Priority Priority { get; }

        public int StartOffset
        {
            get
            {
                return this.m_startOffset;
            }
            set
            {
                this.m_startOffset = value;
            }
        }
    }
}

